home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / ansi / hercules.zip / HERCBIOS.ASM < prev    next >
Assembly Source File  |  1986-09-04  |  11KB  |  407 lines

  1. ;*******************************************************
  2. ;*
  3. ;*    Main program file for HERCBIOS
  4. ;*
  5. ;*        Dave Tutelman - 8/86
  6. ;*
  7. ;*------------------------------------------------------
  8. ;*    
  9. ;*    INT10 -- acts as pre-handler for video interrupts
  10. ;*    (BIOS calls) for Hercules & SuperComputer
  11. ;*    monochrome graphics board.  Calls real BIOS
  12. ;*    if not a Hercules special. Handled here are:
  13. ;*
  14. ;*    Fn 0    Set mode (only 6 & 8)
  15. ;*    and all functions, when in mode 6 or 8.
  16. ;*    Actually, we've only implemented:
  17. ;*    Fn 2    Set cursor position
  18. ;*    Fn 3    Read cursor position
  19. ;*    Fn 5    New display page
  20. ;*    Fn 9    Write character with attribute
  21. ;*    Fn 10    Write character
  22. ;*    Fn 12    Write pixel
  23. ;*    Fn 13    Read pixel
  24. ;*    Fn 14    Teletypewriter-style character write
  25. ;*    Fn 15    Get video status
  26. ;*
  27. ;*    The only allowable modes for these boards are:
  28. ;*    6    IBM graphics (we handle it, but poor aspect ratio).
  29. ;*    7    Monochrome (with 2 pages)
  30. ;*    8    Hercules graphics mode.
  31. ;*
  32. ;**********************************************************
  33. ;
  34. INCLUDE    hercbios.h
  35.  
  36. extrn    writechar:near,tty:near,scroll_up:near,scroll_down:near
  37. extrn    scr_start:word,scr_length:word,num_rows:byte
  38. extrn    wr_pixel:near
  39. extrn    end_herc:near
  40. public    exit_herc_bios,int10,vid_vector
  41. public    set_mode,set_curs,read_curs,new_page,status
  42. ;-----------------------------------------
  43. page
  44. ;************************************************************
  45. ;*
  46. ;*    Install the Hercules video handler
  47. ;*
  48. ;************************************************************
  49. cseg    segment    public
  50.     assume    cs:cseg,ds:cseg
  51.  
  52.     ORG    100h
  53. ;
  54. START:
  55. ;
  56.     push    ax
  57.     push    es
  58.     push    ds
  59. ;
  60.     xor    ax,ax        ; zero the acc
  61.     mov    es,ax        ; ES points to zero (interrupt vector)
  62.     ; Get ROM BIOS video entry point, and save in "rom_bios"
  63.     mov    ax,es:[4*VIDI]
  64.     mov    word ptr cs:rom_bios,ax
  65.     mov    ax,es:[4*VIDI+2]
  66.     mov    word ptr cs:rom_bios+2,ax
  67.     ; Now plant the HERCBIOS entry point in interrupt vector
  68.     mov    ax,offset int10    ; address of video handler to AX
  69.     mov    es:[4*VIDI],ax    ; and store it in interrupt vector 10H
  70.     mov    ax,cs        ; same for the segment of video handler
  71.     mov    es:[4*VIDI+2],ax    ; ...
  72. ;
  73. ;   Leave the message that we're installed
  74.     mov    ax,cs        ; DS:DX pointing to message
  75.     mov    ds,ax
  76.     mov    dx,offset install_msg
  77.     mov    ah,9        ; display-string function
  78.     int    21h
  79.  
  80.     pop    ds
  81.     pop    es
  82.     pop    ax
  83. ;
  84.     mov    dx,offset end_herc    ; set dx to end of this program
  85.     int    27H        ; terminate, but stay resident
  86. ;
  87. install_msg    db    "BIOS for Hercules-compatible Graphics - "
  88.     db        "(DMT Aug 1986)",10,13,'$'
  89. page
  90. ;************************************************************
  91. ;*
  92. ;*    Beginning of video interrupt handler
  93. ;*
  94. ;************************************************************
  95. ;
  96. ;
  97. int10    proc    far
  98. ;
  99.     sti            ; allow further interrupts
  100.     push    ds        ; save DS
  101.     push    ax        ; save AX
  102.     mov    ax,bios_data    ; bios data segment --> AX
  103.     mov    ds,ax        ; now put bios data segment in DS
  104.     assume    ds:bios_data    ; and tell assembler about it
  105. ;            ; check current mode
  106.     mov    ah,video_mode    ; get current mode
  107.     cmp    ah,herc_mode    ; test for a graphics mode
  108.     je    herc_bios
  109.     cmp    ah,ibm_mode
  110.     je    herc_bios
  111. ;            ; setmode to a graphics mode?
  112.     pop    ax        ; restore AX
  113.     push    ax        ; ...but leave it on stack
  114.     cmp    ax,0006        ; Fn = set to IBM hi-res mode?
  115.     je    herc_bios
  116.     cmp    ax,0008        ; Fn = set to Herc graphics mode?
  117.     je    herc_bios
  118. ;
  119. norm_bios:        ; if we get here, just go to real BIOS
  120.     pop    ax        ; restore stack to pre-interrupt state
  121.     pop    ds
  122.     db    0EAh    ; opcode for FAR JUMP to rom_bios
  123. rom_bios    dd    ?    ; normal video bios address (in ROM)
  124. ;
  125. herc_bios:        ; jump table for special Hercules BIOS
  126. ;
  127.     pop    ax    ; restore ax
  128.     push    bx    ; save regs
  129.     push    cx
  130.     push    dx
  131.     push    si
  132.     push    di
  133.     push    es
  134. ;
  135.     push    ax
  136.     mov    al,ah        ; function # to AX
  137.     xor    ah,ah
  138.     shl    ax,1        ; *2 for word vector
  139.     mov    si,ax        ; put in SI to index into vector
  140.     pop    ax        ; restore old AX
  141.     cmp    si,offset vid_vec_end-offset vid_vector
  142.                 ; function number within range?
  143.     jge    exit_herc_bios    ; function number out of range
  144.     add    si,offset vid_vector
  145.     jmp    word ptr cs:[si]
  146.                 ; jump to routine via vector
  147. ;
  148.  
  149. vid_vector:        ; jump vector for hercules video routines
  150.     dw    offset set_mode            ; 0 = set mode
  151.     dw    offset exit_herc_bios        ; 1 = cursor type (NA)
  152.     dw    offset set_curs            ; 2 = set cursor position
  153.     dw    offset read_curs        ; 3 = read cursor position
  154.     dw    offset exit_herc_bios        ; 4 = light pen (NA)
  155.     dw    offset new_page            ; 5 = choose active page
  156.     dw    offset scroll_up        ; 6 = scroll up
  157.     dw    offset scroll_down        ; 7 = scroll down
  158.     dw    offset exit_herc_bios        ; 8 = read character (NA)
  159.     dw    offset writechar        ; 9 = write char & attribute
  160.     dw    offset writechar        ;10 = write character
  161.     dw    offset exit_herc_bios        ;11 = set color palette (NA)
  162.     dw    offset wr_pixel            ;12 = write pixel
  163.     dw    offset wr_pixel            ;13 = read pixel
  164.     dw    offset tty            ;14 = teletype write
  165.     dw    offset status            ;15 = return video state
  166. vid_vec_end:
  167. ;
  168. exit_herc_bios:
  169.     pop    es    ; restore regs
  170.     pop    di
  171.     pop    si
  172.     pop    dx
  173.     pop    cx
  174.     pop    bx
  175.     pop    ds
  176.     iret        ; and return
  177. page
  178. ;********************************************************************
  179. ;*
  180. ;*    FUNCTION 0 - SET VIDEO MODE
  181. ;*
  182. ;*    Only gets here to set a hi-res graphics mode
  183. ;*        6=IBM
  184. ;*        8=Hercules
  185. ;*    [ AX destroyed ]
  186. ;*
  187. ;*******************************************************************
  188. ;
  189. set_mode:
  190. ;            ; is it a graphics mode?
  191.     cmp    al,herc_mode    ; set to hercules mode?
  192.     je    g_mode
  193.     cmp    al,ibm_mode    ; set to IBM mode?
  194.     je    g_mode
  195.                 ; Neither. Leave it to normal BIOS
  196.     pop    es        ; restore regs
  197.     pop    di
  198.     pop    si
  199.     pop    dx
  200.     pop    cx
  201.     pop    bx
  202.     pop    ds
  203.     jmp    vid_bios    ; and go to MPX-16 BIOS
  204. ;
  205. g_mode:    mov    video_mode,al    ; save video mode in BIOS data area
  206.     mov    active_page,ah    ; zero the active page in BIOS data
  207.     mov    n_cols,90    ; 90 character columns in graphics mode
  208. ;
  209. ;*  clear display area
  210.     mov    ax,pixbase    ; get starting address
  211.     mov    es,ax        ; page base to ES
  212.     mov    cx,8000H    ; word counter
  213.     mov    di,0        ; start at beginning of display
  214.     cld            ; direction "up"
  215.     xor    ax,ax        ; zero AX
  216.     rep    stosw        ; write zero to both pages
  217. ;
  218. ;*  load the 6845 internal registers
  219. ;
  220. ;            ; first set up the loop
  221.     push    ds        ; save DS
  222.     mov    ax,cs        ; get cseg into DS
  223.     mov    ds,ax
  224.     assume    ds:cseg
  225.     mov    dx,vid_port    ; 6845 index port address to DX
  226.     mov    si,offset vid_parm_table
  227.                 ; table pointer to SI
  228.     mov    cx,16        ; 16 parameters in table
  229.     xor    ax,ax        ; zero AX (AH will be index counter)
  230. ;            ; now execute the loop
  231. init_6845_loop:
  232.     mov    al,ah        ; index counter to AL
  233.     out    dx,al        ; output index to 6845
  234.     inc    dx        ; point DX to data reg
  235.     mov    al,[si]        ; get table entry
  236.     out    dx,al        ; output to 6845 data reg
  237.     dec    dx        ; point DX back to index reg
  238.     inc    ah        ; bump index counter
  239.     inc    si        ; bump table pointer
  240.     loop    init_6845_loop
  241.     pop    ds        ; restore DS
  242.     assume    ds:bios_data    ; restore DS assumed
  243. ;
  244. ;*  now set the 6845 control register
  245.     mov    dx,vid_port+4    ; control port address
  246.     mov    al,0AH        ; graphics control byte
  247.     cmp    active_page,0    ; get current page
  248.     je    pg0_F0        ; skip if zero
  249.     or    al,80H        ; page 1 to control byte
  250. pg0_F0:    out    dx,al        ; and ship to 6845
  251.     mov    chip_ctrl,al    ; also save in bios data area
  252. ;
  253. ;*  save cursor position (0,0) in bios data area
  254.     xor    ax,ax        ; zero AX
  255.     mov    curs_pos,ax    ; write zero to pg.0 cursor postion
  256.     mov    curs_pos+2,ax    ; write zero to pg.1 cursor postion
  257. ;
  258. ;*  initialize scrolling parameters
  259. ;
  260.     cmp    video_mode,herc_mode
  261.     je    h_parm
  262.     mov    cs:scr_start,180    ; IBM parameters
  263.     mov    cs:scr_length,3690    ;
  264.     mov    cs:num_rows,42        ;
  265.     jmp    parm_done
  266. h_parm:    mov    cs:scr_start,270    ; Herc parameters
  267.     mov    cs:scr_length,3645    ;
  268.     mov    cs:num_rows,28        ;
  269. parm_done:
  270. ;
  271.     jmp    exit_herc_bios
  272. ;
  273. ;*  table of 6845 chip parameters
  274. ;
  275. vid_parm_table    db    53,45,46,7,91,2,87,87,2,3,62H,3,0,0,0,0
  276. ;vid_parm_table    db    54,45,46,8,91,2,87,87,2,3,62H,3,0,0,0,0
  277.                         ;DMT's monitor
  278. page
  279. ;********************************************************************
  280. ;*
  281. ;*    FUNCTION 2 - SET CURSOR POSITION
  282. ;*
  283. ;*    DX = new row (DH) and column (DL)
  284. ;*    BH = display page number
  285. ;*
  286. ;********************************************************************
  287. ;
  288. set_curs:
  289. ;
  290. ; *   save in BIOS data area
  291.     mov    bl,bh        ; page # to bl
  292.     xor    bh,bh        ; zero bh (page # = BX)
  293.